package com.android.lovepick.map;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.location.Location;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.android.lovepick.util.Constant;
import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.GeoPoint;
import com.baidu.mapapi.LocationListener;
import com.baidu.mapapi.MKAddrInfo;
import com.baidu.mapapi.MKBusLineResult;
import com.baidu.mapapi.MKDrivingRouteResult;
import com.baidu.mapapi.MKLocationManager;
import com.baidu.mapapi.MKPlanNode;
import com.baidu.mapapi.MKPoiInfo;
import com.baidu.mapapi.MKPoiResult;
import com.baidu.mapapi.MKSearch;
import com.baidu.mapapi.MKSearchListener;
import com.baidu.mapapi.MKSuggestionResult;
import com.baidu.mapapi.MKTransitRouteResult;
import com.baidu.mapapi.MKWalkingRouteResult;

/**
 * @author liutong
 */
public class MapHelper implements MKSearchListener
{
	private static final String MAPSEARCH_TAG = "MapHelper";
	private MKAddrInfo mAddrInfo = null;
	private MKDrivingRouteResult mDriveResult = null;
	private MKPoiResult mPoiResult = null;
	private BMapManager mBMapManager;
	private MKLocationManager mLocationManager = null;
	private Handler mHandler;

	private MKSearch mMKSearch;

	private List<Map<String, Object>> poiList = null;

	public MapHelper(BMapManager mapManager, Handler handler)
	{
		this.mBMapManager = mapManager;
		this.mHandler = handler;
	}

	private LocationListener locationListener = new LocationListener()
	{

		public void onLocationChanged(Location location)
		{
			if (location != null)
			{
				// TODO Auto-generated method stub
				int latitudeE6 = (int) (location.getLatitude() * 1E6);
				Log.i(MAPSEARCH_TAG, "latitude:" + String.valueOf(latitudeE6));
				int longitudeE6 = (int) (location.getLongitude() * 1E6);
				Log.i(MAPSEARCH_TAG, "longitude:" + String.valueOf(longitudeE6));
				GeoPoint geoPoint = new GeoPoint(latitudeE6, longitudeE6);
				getAddrFromGeo(geoPoint);
			}
		}
	};

	public void getCurrentLocation()
	{
		this.mLocationManager = mBMapManager.getLocationManager();

		mLocationManager.requestLocationUpdates(locationListener);
	}

	/**
	 * 使用百度地图搜索驾车路线, 并在地图上展示其中的一条路线.
	 * 
	 * @param startPoint
	 *            起点
	 * @param endPoint
	 *            终点
	 */
	public void searchDrivingRoute(GeoPoint startPoint, GeoPoint endPoint)
	{
		MKPlanNode start = new MKPlanNode();
		start.pt = startPoint;
		MKPlanNode end = new MKPlanNode();
		end.pt = endPoint;

		mMKSearch = new MKSearch();
		mMKSearch.init(mBMapManager, this);
		// 驾车路线搜索策略, 时间优先
		mMKSearch.setDrivingPolicy(MKSearch.ECAR_TIME_FIRST);
		Log.i(MAPSEARCH_TAG, "driving search start..");
		mMKSearch.drivingSearch(null, start, null, end);
	}

	public void searchPoi(String city, String key)
	{
		mMKSearch = new MKSearch();
		mMKSearch.init(mBMapManager, this);
		Log.i(MAPSEARCH_TAG, "poi search start...");
		mMKSearch.poiSearchInCity(city, key);
	}

	public void getAddrFromGeo(GeoPoint point)
	{
		mMKSearch = new MKSearch();
		mMKSearch.init(mBMapManager, this);
		Log.i(MAPSEARCH_TAG, "reverse geocode start...");
		mMKSearch.reverseGeocode(point);
	}

	public void onGetAddrResult(MKAddrInfo result, int error)
	{
		// TODO Auto-generated method stub
		Log.i(MAPSEARCH_TAG, "AddrINfo error:" + String.valueOf(error));
		if (result == null)
		{
			Log.i(MAPSEARCH_TAG, "AddrInfo: no result");
		}
		this.mAddrInfo = result;
		mLocationManager.removeUpdates(locationListener);
		Message msg = new Message();
		msg.what = Constant.MSG_ADDRSEARCH_COMPLETE;
		mHandler.sendMessage(msg);
	}

	public void onGetBusDetailResult(MKBusLineResult result, int error)
	{
		// TODO Auto-generated method stub

	}

	public void onGetDrivingRouteResult(MKDrivingRouteResult result, int error)
	{
		// TODO Auto-generated method stub
		Log.i(MAPSEARCH_TAG,
				"MKDrivingRouteResult error: " + String.valueOf(error));
		if (result == null)
		{
			Log.i(MAPSEARCH_TAG, "MKDrivingRouteResult: no result");
		}
		this.mDriveResult = result;
		Message msg = new Message();
		msg.what = Constant.MSG_DRIVESEARCH_COMPLETE;
		mHandler.sendMessage(msg);
	}

	public void onGetPoiResult(MKPoiResult result, int type, int error)
	{
		// TODO Auto-generated method stub
		Log.i(MAPSEARCH_TAG, "MKPoiResult error:" + String.valueOf(error));
		Log.i(MAPSEARCH_TAG, "MKPoiResult type:" + String.valueOf(type));
		if (result == null)
		{
			Log.i(MAPSEARCH_TAG, "MKPoiResult: no result.");
		}
		else
		{
			this.mPoiResult = result;

			ArrayList<MKPoiInfo> poiInfos = result.getAllPoi();
			if (poiInfos != null)
			{
				// Log.i(MAPSEARCH_TAG, poiInfos.toString());
				poiList = new ArrayList<Map<String, Object>>();
				for (MKPoiInfo poiInfo : result.getAllPoi())
				{
					HashMap<String, Object> map = new HashMap<String, Object>();
					map.put("poi_name", poiInfo.name);
					Log.i(MAPSEARCH_TAG, "name:" + poiInfo.name);
					map.put("poi_addr", poiInfo.address);
					Log.i(MAPSEARCH_TAG, "addrress:" + poiInfo.address);
					map.put("poi_geo", poiInfo.pt);
					poiList.add(map);
				}
			}
		}

		Message msg = new Message();
		msg.what = Constant.MSG_POISEARCH_COMPLETE;
		mHandler.sendMessage(msg);

	}

	public void onGetSuggestionResult(MKSuggestionResult result, int error)
	{
		// TODO Auto-generated method stub

	}

	public void onGetTransitRouteResult(MKTransitRouteResult result, int error)
	{
		// TODO Auto-generated method stub

	}

	public void onGetWalkingRouteResult(MKWalkingRouteResult result, int error)
	{
		// TODO Auto-generated method stub

	}

	public MKDrivingRouteResult getDriveResult()
	{
		return mDriveResult;
	}

	public MKPoiResult getPoiResult()
	{
		return mPoiResult;
	}

	public MKAddrInfo getAddrInfo()
	{
		return mAddrInfo;
	}

	public List<Map<String, Object>> getPoiList()
	{
		return poiList;
	}
}
